﻿using UnityEngine;
using UnityEditor;
using System.Collections.Generic;

namespace CWM.Skinn.FFD
{
    [CustomEditor(typeof(LatticeMarker))]
    [CanEditMultipleObjects]
    public class LatticeMarkerInspector : Editor
    {
        private static Object[] m_targets = new Object[0];

        public static Editor Inspector { get; private set; }
        [MenuItem("CONTEXT/LatticeMarker/Edit Inspector Script", false, 10)]
        public static void Open(MenuCommand command) { if (Inspector) AssetDatabase.OpenAsset(MonoScript.FromScriptableObject(Inspector), 0); }
        public void OnEnable() { Inspector = this; }

        public override void OnInspectorGUI()
        {
            m_targets = targets;

            DrawDefaultInspector();

            var t = target as LatticeMarker; if (!t.lattice) return;
            EditorGUILayout.LabelField(" ");
            EditorGUILayout.LabelField("");
            if (GUI.Button(GUILayoutUtility.GetLastRect(), "Select Lattice"))
            {
                Selection.activeGameObject = t.lattice.gameObject;
                Repaint();
            }
            EditorGUILayout.LabelField(" ");
            EditorGUILayout.LabelField("");

            if (GUI.Button(GUILayoutUtility.GetLastRect(), "Smooth All"))
            {
                var smr = !t.lattice || !t.lattice.skinnedMeshRender  ? null : t.lattice.skinnedMeshRender;
                BoneWeight[] boneWeights;
                if(smr && SkinnEx.SmoothWeights(smr, out boneWeights, null, 16))
                {
                    Undo.RecordObject(smr, "Smooth");
                    smr.sharedMesh = smr.sharedMesh.Clone() as Mesh;
                    smr.sharedMesh.boneWeights = boneWeights;
                }
            }

            EditorGUILayout.LabelField("");
            if (GUI.Button(GUILayoutUtility.GetLastRect(), "Smooth Selection"))
            {
                var smr = !t.lattice || !t.lattice.skinnedMeshRender ? null : t.lattice.skinnedMeshRender;
                if (SkinnEx.IsNullOrNotVailid(smr)) smr = null;

                if (smr)
                {
                    var bones = smr.bones;
                    var smoothedBones = new List<int>();

                    foreach (var bone in targets)
                    {
                        var marker = bone as LatticeMarker; if (!marker) continue;
                        var boneIndex = bones.GetIndex(marker.transform);
                        if (boneIndex < 0) smoothedBones.Add(boneIndex);
                    }

                    var smoothing = new SmoothingOption() { SmoothableBones = smoothedBones};

                    BoneWeight[] boneWeights;
                    if (SkinnEx.SmoothWeights(smr, out boneWeights, smoothing, 16))
                    {
                        Undo.RecordObject(smr, "Smooth");
                        smr.sharedMesh = smr.sharedMesh.Clone() as Mesh;
                        smr.sharedMesh.boneWeights = boneWeights;
                    }
                }
               
            }

            GenerateMeshMarkers();
        }

        public void GenerateMeshMarkers()
        {
            for (int i = 0; i < m_targets.Length; i++)
            {
                var marker = m_targets[i] as LatticeMarker;
                if (marker.weights.Count < 1) continue;
                var mf = marker.GetMeshFilter; if (!mf) continue;
                var mesh = marker.GetMeshFilter.sharedMesh;
                var scaleOffset = marker.lattice.markerSize;
                var scale = marker.transform.localScale;
                var maxScale = Mathf.Max(Mathf.Abs(scale.x), Mathf.Abs(scale.y), Mathf.Abs(scale.z));
                scale = new Vector3(maxScale, maxScale, maxScale);
                if (SkinnEx.EnforceObjectName(mesh) != SkinnEx.BoxPrimativeID(Color.white, Vector3.one, scale, scaleOffset))
                {
                    mf.sharedMesh = SkinnEx.BoxPrimative(Color.white, Vector3.one, scale, scaleOffset, mesh);
                    mf.sharedMesh.hideFlags = HideFlags.HideAndDontSave;
                }
            }
        }

    }
}